package wyy

import (
	"api-go/cache"
	"api-go/serializer"
	migu "api-go/service/v1/migu"
	"api-go/util"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"

	"github.com/go-redis/redis/v8"
)

// 歌曲所需信息
type Song struct {
	Ids   string `form:"id"`
	Br    string `form:"br"` //1.mp3 128k 2.320k 3.flag/ape
	Limit string `form:"limit"`
}

//获取歌曲链接
func (service *Song) SongUrl() *serializer.Response {

	if val := service.Ids; val != "" {
		// service.Ids = fmt.Sprintf("[%v]", val)
		service.Ids = val
	} else {
		// service.Ids = "[1483891561]"
		service.Ids = "1483891561"
	}

	if val := service.Br; val != "" {
		service.Br = val
	} else {
		service.Br = "1"
	}

	if service.Br == "1" {
		service.Br = "999000"
	} else if service.Br == "2" {
		service.Br = "mp3"
	} else {
		service.Br = "flac"
	}

	// url := "https://interface3.music.163.com/api/song/enhance/player/url?ids=" + service.Ids + "&br=" + service.Br
	// res, err := util.Get(url)
	//改用第三方接口
	client := &http.Client{}
	data := url.Values{}
	var urlStr string
	if service.Br == "999000" {
		urlStr = "https://interface3.music.163.com/api/song/enhance/player/url"
		data.Set("ids", "["+service.Ids+"]")
		data.Set("br", service.Br)
	} else {
		urlStr = "http://music.fy6b.com/index/mp3orflac"
		data.Set("type", "netease")
		data.Set("id", service.Ids)
		data.Set("option", service.Br)
	}

	r, _ := http.NewRequest("POST", urlStr, strings.NewReader(data.Encode())) // URL-encoded payload
	r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	r.Header.Add("X-Forwarded-For", util.RandIp())
	resp, err := client.Do(r)
	if err != nil {
		return serializer.ErrorResponse(serializer.CodeUnknownError)
	}
	defer resp.Body.Close()
	datas, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return serializer.ErrorResponse(serializer.CodeUnknownError)
	}
	// fmt.Println(string(data))
	//赋值用于后面将string转为json
	bodyMapData := map[string]interface{}{}
	err = json.Unmarshal(datas, &bodyMapData)
	if err != nil {
		return serializer.ErrorResponse(serializer.CodeUnknownError)
	}

	out := map[string]interface{}{}

	urlStr = "https://music.163.com/api/v3/song/detail?c=[{id:" + service.Ids + "}]"

	ress, errs := util.Get(urlStr)
	if errs != nil {
		return serializer.ErrorResponse(serializer.CodeUnknownError)
	}
	if len(ress.(map[string]interface{})["songs"].([]interface{})) > 0 {
		resss := ress.(map[string]interface{})["songs"].([]interface{})[0].(map[string]interface{})
		out["id"] = resss["id"]
		out["album"] = resss["al"].(map[string]interface{})["name"]
		out["name"] = resss["name"].(string)
		out["singer"] = resss["ar"].([]interface{})[0].(map[string]interface{})["name"].(string)
		out["picUrl"] = resss["al"].(map[string]interface{})["picUrl"]
	} else {
		out["id"] = service.Ids
		out["album"] = "获取失败"
		out["name"] = "获取失败"
		out["singer"] = "获取失败"
		out["picUrl"] = "http://qt.music.canace.cn/avatar.png"
	}
	out["platform"] = "wyy"
	if service.Br == "999000" {
		service.Br = "1"
		res := bodyMapData["data"].([]interface{})[0].(map[string]interface{})
		//此处res["code"]为interface{}的float64类型，需要转为string去比较
		if strconv.FormatFloat(res["code"].(float64), 'f', -1, 64) == "200" {
			out["url"] = res["url"]
			out["size"] = res["size"]
			out["br"] = res["br"]
		} else {
			// out["url"] = kw.UsingKwSong(out["name"].(string), out["singer"].(string), service.Br)
			out["url"] = migu.UsingMiguSong(out["name"].(string), out["singer"].(string), service.Br)

		}

	} else {
		out["url"] = bodyMapData["url"]
		out["size"] = bodyMapData["size"]
		out["br"] = bodyMapData["br"]
	}

	//获取歌词
	urlStr = "https://music.163.com/api/song/lyric?lv=-1&kv=-1&tv=-1&id=" + service.Ids
	b, errs := util.Get(urlStr)
	if errs != nil {
		return serializer.ErrorResponse(serializer.CodeUnknownError)
	}
	if b.(map[string]interface{})["lrc"] != nil {
		out["lyric"] = b.(map[string]interface{})["lrc"].(map[string]interface{})["lyric"]
	} else {
		out["lyric"] = "failed"
	}
	return serializer.OkResponse(out)
}

//获取歌曲详细信息
func (service *Song) SongInfo() *serializer.Response {

	if val := service.Ids; val != "" {
		service.Ids = fmt.Sprintf("[{\"id\":%v}]", val)
	} else {
		service.Ids = "[{id:1483891561}]"
	}

	url := "https://music.163.com/api/v3/song/detail?c=" + service.Ids

	res, err := util.Get(url)
	if err != nil {
		return err
	}
	return serializer.OkResponse(res)
}

//获取歌曲歌词
func (service *Song) SongLyric() *serializer.Response {
	if val := service.Ids; val != "" {
		service.Ids = val
	} else {
		service.Ids = "1483891561"
	}

	url := "https://music.163.com/api/song/lyric?lv=-1&kv=-1&tv=-1&id=" + service.Ids

	res, err := util.Get(url)
	if err != nil {
		return err
	}
	return serializer.OkResponse(res)
}

//获取新歌 不支持offset
func (service *Song) SongNew() *serializer.Response {
	if val := service.Limit; val != "" {
		service.Limit = val
	} else {
		service.Limit = "20"
	}
	//定义redis key和判断redis是否有该值
	redisKey := "wyy-song-new-" + service.Limit
	redisResult, err := cache.RedisClient.Get(ctx, redisKey).Result()
	//若redis没有该值则执行获取
	if err == redis.Nil {

		url := "https://music.163.com/api/personalized/newsong?type=recommend&areaId=0&limit=" + service.Limit

		res, err := util.WyyGet(url)
		if err != nil {
			return err
		}
		//将结果转为Json数据
		b, e := json.Marshal(res)
		if e != nil {
			fmt.Println(err)
		}
		//转为string存入redis
		e = cache.RedisClient.Set(ctx, redisKey, string(b), 24*time.Hour).Err()
		if e != nil {
			fmt.Println("err1", err)
			return serializer.ErrorResponse(serializer.RedisError)
		}

		return serializer.OkResponse(res)
	} else if err != nil {
		fmt.Println("err2", err)
		return serializer.ErrorResponse(serializer.RedisError)
	} else {
		//将从redis获取的结果（string类型）转为map[string]inerface{}
		bodyMapData := map[string]interface{}{}
		err = json.Unmarshal([]byte(redisResult), &bodyMapData)
		if err != nil {
			fmt.Println("err3", err)
			return serializer.ErrorResponse(serializer.RedisError)
		}
		return serializer.OkResponse(bodyMapData)
	}

}

//其他接口调用酷我接口
func UsingWyySong(name, singer, br string) string {

	if a := usingWyySearch(name, singer); a != "failed" {
		if br == "1" {
			br = "mp3"
		} else if br == "2" {
			br = "mp3"
		} else {
			br = "flac"
		}

		//第三方接口，需要使用post
		client := &http.Client{}
		data := url.Values{}
		urlStr := "http://music.fy6b.com/index/mp3orflac"
		data.Set("type", "netease")
		data.Set("id", a)
		data.Set("option", br)
		r, _ := http.NewRequest("POST", urlStr, strings.NewReader(data.Encode())) // URL-encoded payload
		r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
		r.Header.Add("X-Forwarded-For", util.RandIp())
		resp, err := client.Do(r)
		if err != nil {
			return "failed"
		}
		defer resp.Body.Close()
		datas, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return "failed"
		}
		// fmt.Println(string(data))
		//赋值用于后面将string转为json
		bodyMapData := map[string]interface{}{}
		err = json.Unmarshal(datas, &bodyMapData)
		if err != nil {
			return "failed"
		}

		if bodyMapData["url"] != nil {
			newUrl := bodyMapData["url"].(string)
			return newUrl
		} else {
			return "failed"
		}

	} else {
		return "failed"
	}
}

//用于第三方搜索使用
func usingWyySearch(name, singer string) string {

	key := name + " " + singer
	//此处需要对中文进行转码，否则会无法请求第三方api
	key = url.QueryEscape(key)
	//定义redis key和判断redis是否有该值
	redisKey := "wyy-search-" + name + "-" + singer
	redisResult, err := cache.RedisClient.Get(ctx, redisKey).Result()
	//若redis没有该值则执行获取
	if err == redis.Nil {
		url := "https://music.163.com/api/search/get?s=" + key + "&limit=1&offset=1&type=1"
		res, err := util.Get(url)
		if err != nil {
			fmt.Println(err)
			return "failed1"
		}
		//如果有搜索结果就获取id
		var ress string
		if res.(map[string]interface{})["result"].(map[string]interface{})["songs"] != nil && len(res.(map[string]interface{})["result"].(map[string]interface{})["songs"].([]interface{})) > 0 {
			resss := res.(map[string]interface{})["result"].(map[string]interface{})["songs"].([]interface{})[0].(map[string]interface{})
			ress = strconv.FormatFloat(resss["id"].(float64), 'f', -1, 64)
		} else {
			return "failed"
		}
		//转为string存入redis
		e := cache.RedisClient.Set(ctx, redisKey, ress, 24*time.Hour).Err()
		if e != nil {
			fmt.Println("err1", err)
			return "failed"
		}

		return ress
	} else if err != nil {
		return "failed"
	} else {
		//将从redis获取的结果（string类型）
		return redisResult
	}
}
